package com.example.rabbitboot.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lzh
 * @date 2019/9/11 - 14:03
 */
@Configuration
public class RabbitTopicConfig {

    /**
     * topic
     *
     * Topic Exchange是根据routing key和Exchange的类型将message发送到一个或者多个Queue中，
     * 我们经常拿他来实现各种publish/subscribe，即发布订阅，这也是我们经常使用到的ExchangeType
     *
     * 使用场景：
     *    1.新闻的分类更新
     *    2.同一任务多个工作者协调完成
     *    3.同一问题需要特定人员知晓
     *
     */
    public static final String TOPIC_QUEUE1 = "topic.queue1";
    public static final String TOPIC_QUEUE2 = "topic.queue2";
    public static final String TOPIC_EXCHANGE = "topic.exchange";

    /**
     * 工厂方法 帮助创建队列和交换机
     */
    @Bean
    public Queue getTopicQueue1() {
        return new Queue(TOPIC_QUEUE1);
    }

    @Bean
    public Queue getTopicQueue2() {
        return new Queue(TOPIC_QUEUE2);
    }

    @Bean
    public TopicExchange getTopicExchange() {
        return new TopicExchange(TOPIC_EXCHANGE);
    }


    /**
     * topic类型的Exchange在匹配规则上进行了扩展，它与direct类型的Exchage相似，
     * 也是将消息路由到binding key与routing key相匹配的Queue中，
     *
     * 但这里的匹配规则有些不同，它约定
     *
     * 1.routing key为一个句点号“. ”分隔的字符串 ,
     *   如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
     *
     * 2.binding key与routing key一样也是句点号“. ”分隔的字符串
     *
     * 3.binding key中可以存在两种特殊字符“*”与“#”，用于做模糊匹配，
     *     其中“*”用于匹配一个单词，
     *      “#”用于匹配多个单词（可以是零个）
     *
     *  例如：
     *  因为当前配置的routing key为 lzc.message 和 lzc.#
     *     当发送方的routing key为lzc.lzc 时, 消息只会被  lzc.# 这个队列的交换机监听到;
     *    若发送方的routing key为lzc.message 时 ,
     *    消息会同时被 lzc.message 和 lzc.# 这2个队列的交换机监听到;
     *
     *
     *    lzc.# 可以匹配  lzc.qw.qwe.q1 或 lzc.message 或 lzc.12q.qwe
     *
     *    lzc.*.qwe 可以匹配  lzc.12q.qwe 或 lzc.21w.qwe
     *
     *    !!!!!注意：为了保证消息的分类接收，routingKey一般多使用*号
     *
     *
     */




    @Bean
    public Binding topicBinding1() {
        return BindingBuilder
                .bind(getTopicQueue1())
                .to(getTopicExchange())
                .with("lzc.*.qwe");
    }


    @Bean
    public Binding topicBinding2() {
        return BindingBuilder
                .bind(getTopicQueue2())
                .to(getTopicExchange())
                .with("test.*.qwe");
    }


//    @Bean
//    public Binding topicBinding2() {
//        return BindingBuilder
//                .bind(getTopicQueue2())
//                .to(getTopicExchange())
//                .with("lzc.#");
//    }
}
